import threading

import sys


class locker():
    def __init__(self, defaultTimeout=10):
        self.__lock__ = threading.Lock()
        if not isinstance(defaultTimeout, int):
            raise TypeError("defaultTimeout 必须是 int 类型")
        self.timeout = defaultTimeout

    def lock(self, timeout=None):
        if isinstance(timeout, int):
            return __lockerContext__(self.__lock__, timeout)
        if timeout is not None:
            raise TypeError("timeout 必须是 int 类型")
        if not isinstance(self.timeout, int):
            raise TypeError("locker.timeout 必须是 int 类型")
        return __lockerContext__(self.__lock__, self.timeout)


class __lockerContext__(object):
    def __init__(self, lock, timeout):
        self.__lock__ = lock
        self.__timeout__ = timeout

    def __enter__(self):
        self.__lock__.acquire(self.__timeout__)

    def __exit__(self, exc_type, exc_value, exc_tb):
        self.__lock__.release()


if __name__ == "__main__":
    import time

    lk = locker(100)


    def testA():
        print("A:进入testA,暂停2秒")
        time.sleep(2)
        print("A:准备获取锁")
        with lk.lock():
            print("A:得到锁,锁2秒")
            time.sleep(2)
            print("A:准备释放锁")
        print("A:释放锁")


    def testB():
        print("B:进入testB,准备获取锁")
        with lk.lock():
            print("B:得到锁,锁5秒")
            for i in range(5):
                print("B:" + str(5 - i))
                time.sleep(1)
            print("B:准备释放锁")
        print("B:释放锁")
        time.sleep(1)
        print("B:准备再次获取锁")
        with lk.lock():
            print("B:得到锁")
            time.sleep(1)
            print("B:准备释放锁")
        print("B:释放锁")


    threading.Thread(target=testA).start()
    threading.Thread(target=testB).start()
